﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WJP.Domain.Entitys;

namespace WJP.Domain
{
    /// <summary>
    /// <see cref="int"/>为主键的实体类型
    /// </summary>
    [Serializable]
    public abstract class Entity : Entity<int>, IEntity
    {

    }

    /// <summary>
    /// 实体
    /// </summary>
    [Serializable]
    public abstract class Entity<TPrimaryKey> : ObservableObject, IEntity<TPrimaryKey>, IDirtyAware
    {
        /// <summary>
        /// 实体
        /// </summary>
        public Entity()
        {
            PersistenceStatus = PersistenceStatus.New;
        }

        #region 唯一的标识属性 Id
        /// <summary>
        /// 唯一的标识属性
        /// </summary>
        public TPrimaryKey Id
        {
            get { return (TPrimaryKey)GetProperty(); }
            set { SetProperty(value); }
        }
        #endregion

        #region Interface

        /// <summary>
        /// 实体持久化状态
        /// </summary>
        public PersistenceStatus PersistenceStatus { get; set; }

        /// <summary>
        /// 是否脏数据
        /// <para></para>如果当前组合对象树中任意部分变更了，则返回 true
        /// </summary>
        public bool IsDirty
        {
            get
            {
                if (PersistenceStatus == PersistenceStatus.Unchanged)
                    return false;
                else
                    return true;
            }
        }

        /// <summary>
        /// 递归将整个组合对象树都标记为未变更状态
        /// </summary>
        public void MarkSaved()
        {
            PersistenceStatus = PersistenceStatus.Unchanged;
        }

        #endregion

        /// <summary>
        /// 通过实体类型反射构造一个新的实体
        /// </summary>
        /// <param name="entityType"></param>
        /// <returns></returns>
        public static Entity<TPrimaryKey> New(Type entityType)
        {
            return Activator.CreateInstance(entityType) as Entity<TPrimaryKey>;
        }

        /// <summary>
        /// 标记当前对象为需要保存的状态
        /// </summary>
        public void MarkModifiedIfUnchanged()
        {
            if (PersistenceStatus != PersistenceStatus.Unchanged)
                return;
            PersistenceStatus = PersistenceStatus.Modified;
        }
    }
}
